home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1996 #15
/
Monster Media Number 15 (Monster Media)(July 1996).ISO
/
prog_c
/
cuj0696.zip
/
DWYER.ZIP
/
LIB
/
RANDMZJ.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-03-26
|
5KB
|
175 lines
/* ============ */
/* randmzj.c */
/* ============ */
#include <defcodes.h>
/* ------------------- */
/* FUNCTION PROTOTYPES */
/* ------------------- */
# undef F
# if defined(__STDC__) || defined(__PROTO__)
# define F( P ) P
# else
# define F( P ) ()
# endif
/* INDENT OFF */
static long DEK_rand F((void));
extern int IRand_MZ F((void));
extern long LRand_MZ F((void));
extern double Rand_MZ F((void));
extern void Rand_MZ_Init F((unsigned long));
extern void VRand_MZ F((double *, int));
# undef F
/* INDENT ON */
#define TWOM24 1.0/TWOP24 /* 2^(-24) */
#define TWOP24 16777216.0 /* 2^24 */
#define P24MASK 16777215L /* 2^24-1 */
/* INDENT OFF */
static double Seeds[24] =
{
4138572.*TWOM24, 16412963.*TWOM24, 5060164.*TWOM24, 3954602.*TWOM24,
11488643.*TWOM24, 11099381.*TWOM24, 10909270.*TWOM24, 564186.*TWOM24,
14261907.*TWOM24, 10716489.*TWOM24, 10042238.*TWOM24, 14709425.*TWOM24,
7010471.*TWOM24, 15189851.*TWOM24, 1616330.*TWOM24, 10844364.*TWOM24,
8026029.*TWOM24, 13538854.*TWOM24, 983044.*TWOM24, 3024518.*TWOM24,
14475343.*TWOM24, 5142119.*TWOM24, 4187065.*TWOM24, 764925.*TWOM24
};
/* INDENT ON */
static double Carry = 0;
static int i24 = 24, j24 = 10;
/* ==================================================================== */
/* Rand_MZ - Returns uniform variate by method of Marsaglia-Zaman-James */
/* ==================================================================== */
/* ------------------------------------------------------------ */
/* The source document for this generator is: */
/* */
/* F. James, A review of pseudorandom number generators, */
/* Computer Physics Communications 60(1990) 329-344. */
/* ------------------------------------------------------------ */
double
Rand_MZ(void)
{
double NextRand;
NextRand = Seeds[i24 - 1] - Seeds[j24 - 1] - Carry;
if (NextRand >= 0)
{
Carry = 0;
}
else
{
++NextRand;
Carry = TWOM24;
}
Seeds[i24 - 1] = NextRand;
--i24;
if (i24 <= 0)
{
i24 = 24;
}
--j24;
if (j24 <= 0)
{
j24 = 24;
}
return NextRand;
}
#define FULL_SIZE ((unsigned)RAND_MAX + 1U)
/* --------------------------------------------- */
/* IRand_MZ - Returns Standard C Uniform Variate */
/* --------------------------------------------- */
int
IRand_MZ(void)
{
return((unsigned) (Rand_MZ() * (double) FULL_SIZE) & RAND_MAX);
}
/* ----------------------------------------------- */
/* LRand_MZ - Returns Uniform Variate of Type Long */
/* ----------------------------------------------- */
long
LRand_MZ(void)
{
return((long) (Rand_MZ() * TWOP24));
}
/* ------------------------------------------------------- */
/* VRand_MZ - Returns Vector of Uniform Variates in [0, 1) */
/* ------------------------------------------------------- */
void
VRand_MZ(double *RandVec, int VecLen)
{
int k;
for (k = 0; k < VecLen; ++k)
{
RandVec[k] = Rand_MZ();
}
}
static unsigned long RandSeed;
/* ------------------------------------------- */
/* DEK_rand - From Knuth vol 2, p 102, line 26 */
/* ------------------------------------------- */
static
long (DEK_rand) (void)
{ /* Knuth Random Numbers */
/* Knuth Generator Returns a 24-Bit Integer */
RandSeed = RandSeed * 1664525 + 1;
return((unsigned long) ((RandSeed >> 8) & P24MASK));
}
/* ------------------------------------------------------------------ */
/* Rand_MZ_Init - Initializes Marsaglia-Zaman Random Number Generator */
/* ------------------------------------------------------------------ */
void
Rand_MZ_Init(unsigned long NewSeed)
{
int k;
RandSeed = NewSeed;
/* --------------------- */
/* Warm up the generator */
/* --------------------- */
for (k = 1; k <= 100; ++k)
{
DEK_rand();
}
for (k = 1; k <= (sizeof(Seeds) / sizeof(double)); ++k)
{
long NextRand = DEK_rand();
Seeds[k - 1] = (double) NextRand *TWOM24;
P(printf("Seeds[%2d] = %.15e\n", k + 1, Seeds[k]));
}
}
# if defined(TEST_RAND_MZ)
void
main()
{
int k;
Rand_MZ_Init(341055109L);
for (k = 1; k <= 50; ++k)
{
double NextRand = Rand_MZ();
printf("NextLongRand # %2d = %10.1f\n", k, NextRand * TWOP24);
}
for (k = 1; k <= 50; ++k)
{
int NextRand = IRand_MZ();
printf("NextIntRand # %2d = %5d\n", k, NextRand);
}
}
# endif